﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Mvc2.Models;
using Lilium.Web.Mvc.EntityFilters;
using Lilium.Web.Mvc;
using System.Web.Mvc;
using Lilium.Web.Mvc.Metadata;

namespace Mvc2.Services
{
    public enum EvenOddFilterMode
    {
        All,
        Even,
        Odd,
    }

    public class EvenOddFilter : EntityFilter<DataRecord, EvenOddFilterState>
    {
        public EvenOddFilter(ControllerBase controller)
            : base(controller)
        {
        }

        public override IQueryable<DataRecord> Apply(IQueryable<DataRecord> entities)
        {
            if (entities == null) throw new ArgumentNullException("entities");

            switch (State.Mode)
            {
                case EvenOddFilterMode.All:
                    break;
                case EvenOddFilterMode.Even:
                    entities = entities.Where(e => (e.Id & 1) == 0);
                    break;
                case EvenOddFilterMode.Odd:
                    entities = entities.Where(e => (e.Id & 1) == 1);
                    break;
                default:
                    entities = entities.Where(e => false);
                    break;
            }

            return entities;
        }

        public IEnumerable<SelectListItem> GetModeList()
        {
            return (new[] { 
                Tuple.Create("Все", EvenOddFilterMode.All),
                Tuple.Create("Четные", EvenOddFilterMode.Even),  
                Tuple.Create("Нечетные", EvenOddFilterMode.Odd) })

                .Select(p => SelectListExtensions.CreateItem(p.Item1, p.Item2.ToString(), this.State.Mode.ToString()));
        }
    }

    public sealed class EvenOddFilterState : ICloneable, IEquatable<EvenOddFilterState>
    {
        #region public EvenOddFilterMode Mode

        private EvenOddFilterMode m_Mode;

        public EvenOddFilterMode Mode
        {
            get { return m_Mode; }
            set { m_Mode = value; }
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            return this.MemberwiseClone();
        }

        #endregion

        public override int GetHashCode()
        {
            return Mode.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            var other = obj as EvenOddFilterState;
            if (other != null)
                return Equals(other);
            else
                return base.Equals(obj);
        }

        public bool Equals(EvenOddFilterState other)
        {
            return this.Mode == other.Mode;
        }
    }
}